﻿#include "cameradialog.h"
#include "ui_cameradialog.h"
#include <QDebug>
#include <QTimer>
#include <QXmlStreamWriter>
#include <QXmlStreamReader>
#include <QSettings>

#include "toast.h"
#include "ipdialog.h"
void SaveSNToReg(QString sn, QString flag)
{
	QString appName = QCoreApplication::applicationName();
	QSettings app(appName, "Camera");
	app.setValue(flag, sn);
}

CameraDialog::CameraDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::CameraDialog)
{
    ui->setupUi(this);
    setWindowFlags(Qt::WindowCloseButtonHint | Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog);
	m_cameraMgr = CameraManager::getInstance();
	//QStringList list = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation);

	//QString appName = QCoreApplication::applicationName();
	//QSettings app(appName, "Camera");
	//QString str = app.value("SavePath").toString();
	//if (str.isEmpty())
	//{
	//	m_savePath = list.first();
	//	app.setValue("SavePath", m_savePath);
	//}
	//else
	//{
	//	m_savePath = str;
	//}
	
	//m_serialLight = new QSerialPort();

    m_attrMap[BRIGHTNESS] = AttrCtrlBasePtr(new BrightnessAttr(ui->horizontalSlider, ui->lineEdit));
    m_attrMap[DIGITALSHIFT] = AttrCtrlBasePtr(new DigitalShiftAttr(ui->horizontalSlider_2, ui->lineEdit_2));
    m_attrMap[EXPOSURETIME] = AttrCtrlBasePtr(new ExposureTimeAttr(ui->horizontalSlider_3, ui->lineEdit_3));
	m_attrMap[GAMMA] = AttrCtrlBasePtr(new GammaAttr(ui->horizontalSlider_4, ui->lineEdit_4));
	m_attrMap[CONTRAST] = AttrCtrlBasePtr(new ContrastAttr(ui->horizontalSlider_5, ui->lineEdit_5));
	m_attrMap[CONTRASTTHRESHOLD] = AttrCtrlBasePtr(new ContrastThresholdAttr(ui->horizontalSlider_6, ui->lineEdit_6));
	m_attrMap[GAINRAW] = AttrCtrlBasePtr(new GainRawAttr(ui->horizontalSlider_7, ui->lineEdit_7));
    ui->horizontalSlider->setProperty("id", BRIGHTNESS);
    ui->lineEdit->setProperty("id", BRIGHTNESS);
    ui->horizontalSlider_2->setProperty("id", DIGITALSHIFT);
    ui->lineEdit_2->setProperty("id", DIGITALSHIFT);
    ui->horizontalSlider_3->setProperty("id", EXPOSURETIME);
    ui->lineEdit_3->setProperty("id", EXPOSURETIME);

	ui->horizontalSlider_4->setProperty("id", GAMMA);
	ui->lineEdit_4->setProperty("id", GAMMA);

	ui->horizontalSlider_5->setProperty("id", CONTRAST);
	ui->lineEdit_5->setProperty("id", CONTRAST);

	ui->horizontalSlider_6->setProperty("id", CONTRASTTHRESHOLD);
	ui->lineEdit_6->setProperty("id", CONTRASTTHRESHOLD);

	ui->horizontalSlider_7->setProperty("id", GAINRAW);
	ui->lineEdit_7->setProperty("id", GAINRAW);

    QIntValidator* aIntValidator = new QIntValidator;
	ui->lineEdit->setValidator(aIntValidator);
    ui->lineEdit_2->setValidator(aIntValidator);
    

    connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(SliderValueChanged()));
    connect(ui->lineEdit, SIGNAL(editingFinished()), this, SLOT(EditTextChanged()));

    connect(ui->horizontalSlider_2, SIGNAL(valueChanged(int)), this, SLOT(SliderValueChanged()));
    connect(ui->lineEdit_2, SIGNAL(editingFinished()), this, SLOT(EditTextChanged()));

    connect(ui->horizontalSlider_3, SIGNAL(valueChanged(int)), this, SLOT(SliderValueChanged()));
    connect(ui->lineEdit_3, SIGNAL(editingFinished()), this, SLOT(EditTextChanged()));

	connect(ui->horizontalSlider_4, SIGNAL(valueChanged(int)), this, SLOT(SliderValueChanged()));
	connect(ui->lineEdit_4, SIGNAL(editingFinished()), this, SLOT(EditTextChanged()));

	connect(ui->horizontalSlider_5, SIGNAL(valueChanged(int)), this, SLOT(SliderValueChanged()));
	connect(ui->lineEdit_5, SIGNAL(editingFinished()), this, SLOT(EditTextChanged()));

	connect(ui->horizontalSlider_6, SIGNAL(valueChanged(int)), this, SLOT(SliderValueChanged()));
	connect(ui->lineEdit_6, SIGNAL(editingFinished()), this, SLOT(EditTextChanged()));

	connect(ui->horizontalSlider_7, SIGNAL(valueChanged(int)), this, SLOT(SliderValueChanged()));
	connect(ui->lineEdit_7, SIGNAL(editingFinished()), this, SLOT(EditTextChanged()));


    if (m_cameraMgr->IsConnected())
    {
        ui->btnConnect->setText(tr("Disconnect"));
        qDebug()<<"+++++++";
        updateAttributeCtrl();
        qDebug()<<"----------";
    }

    ui->btnConnect->setProperty("connected", m_cameraMgr->IsConnected());

    connect(m_cameraMgr, &CameraManager::disconnectEvent, this, [=]{
        ui->btnConnect->setProperty("connected", false);
        ui->btnConnect->setText(tr("Connect"));
        Toast *w = new Toast(this, tr("Disconnected"), 180, 40);
        w->toast();
        ui->listWidget->setDisabled(false);
        InitListWidget();
        updateAttributeCtrl();
    });

    connect(ui->btnConnect, &QPushButton::clicked, [=]{

        QVariant v = ui->btnConnect->property("connected");
        if (v.toBool())
        {
            m_cameraMgr->Disconnect();
            ui->btnConnect->setProperty("connected", !v.toBool());
            ui->btnConnect->setText(tr("Connect"));
            Toast *w = new Toast(this, tr("Disconnected"), 180, 40);
            w->toast();
            ui->listWidget->setDisabled(false);
            updateAttributeCtrl();
        }
        else{

            bool b = m_cameraMgr->Connect();
            if (b)
            {
                ui->btnConnect->setProperty("connected", !v.toBool());
                ui->btnConnect->setText(tr("Disconnect"));
                Toast *w = new Toast(this, tr("Connect success"), 180, 40);
                w->toast();
                ui->listWidget->setDisabled(true);

                updateAttributeCtrl();
            }
			else
			{
				Toast *w = new Toast(this, tr("Connect fail"), 180, 30);
				w->toast();
			}
        }
    });

    connect(ui->btnSetDefault, &QPushButton::clicked, [=]{
		QListWidgetItem *it = ui->listWidget->currentItem();
		if (it)
		{
			QString in = it->text();
			QString sn = m_cameraMgr->GetSerialNumWithInterfaceName(in);
			SaveSNToReg(sn, "camera");
		}	
    });


    connect(ui->btnRefresh, &QPushButton::clicked, [=]{
        m_cameraMgr->Init();
        InitListWidget();
    });

    QTimer::singleShot(10, [=]{
        InitListWidget();
    });

    connect(ui->listWidget, &QListWidget::currentRowChanged , [=](int row){
        if (row >= 0)
            m_cameraMgr->SelectCameraIndex(row);
    });


    connect(ui->btnSave, &QPushButton::clicked, [=]{

		QString appName = QCoreApplication::applicationName();
		QSettings app(appName, "Camera");
		QVariant v = ui->btnConnect->property("connected");
        if (!v.toBool())
        {
            Toast *w = new Toast(this, tr("Not connected with camera"), 280, 30);
            w->toast();
            return;
        }
        std::vector< XmlCfgItem > cfgItemVec;
        AttrCtrlMap::iterator it = m_attrMap.begin();
        for (; it != m_attrMap.end(); ++it)
        {
            if (it->second)
            {
                Dahua::GenICam::ICameraPtr c = m_cameraMgr->GetCurrentCamera();
                it->second->writeCfg(c, cfgItemVec);
            }
        }
      //  QString dir_str = QString("%1/Config/").arg(QCoreApplication::applicationDirPath());
    //    QStringList list = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
      //  QString path = QFileDialog::getSaveFileName(this, tr("log"), dir_str, "*.wtxml", Q_NULLPTR);

//        if(path.isEmpty())
//        {
//            return;
//        }

        QString path = QString("%1/Config/Camera.cfg").arg(QCoreApplication::applicationDirPath());
        QFile file(path);

     //   QFile file("camera.wtxml");
        if (!file.open(QFile::WriteOnly | QFile::Text)) {
            qDebug() << "Error: Cannot write file: "
                     << qPrintable(file.errorString());
            return ;
        }
        QXmlStreamWriter xmlWriter(&file);
        xmlWriter.setAutoFormatting(true);
        xmlWriter.writeStartDocument();
        xmlWriter.writeStartElement("property");

        std::vector<XmlCfgItem>::iterator it1 = cfgItemVec.begin();
        for (; it1 != cfgItemVec.end(); ++it1)
        {
            xmlWriter.writeStartElement("Item");
            xmlWriter.writeAttribute("name",  QString::fromStdString(it1->name));
            xmlWriter.writeAttribute("value", QString::fromStdString(it1->value));

            xmlWriter.writeEndElement();
        }

        xmlWriter.writeEndElement();
        xmlWriter.writeEndDocument();
        file.close();
         if (file.error()) {
             qDebug() << "Error: Cannot write file: "
                      << qPrintable(file.errorString());
             return ;
         }
    });


    connect(ui->btnLoad, &QPushButton::clicked, [=]{
        QVariant v = ui->btnConnect->property("connected");
        if (!v.toBool())
        {
            Toast *w = new Toast(this, tr("Not connected with camera"), 280, 30);
            w->toast();
            return;
        }
        std::vector< XmlCfgItem > cfgItemVec;


//        QString dir_str = QString("%1/Config").arg(QCoreApplication::applicationDirPath());
//       // QStringList list = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
//        QString path = QFileDialog::getOpenFileName(this, tr("log"), dir_str, ".wtxml", Q_NULLPTR);

//        if(path.isEmpty())
//        {
//            return;
//        }

        QString path = QString("%1/Config/Camera.cfg").arg(QCoreApplication::applicationDirPath());
        QFile file(path);

        if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {  // 以只写模式打开文件
            QXmlStreamReader reader(&file);

            // 解析 XML，直到结束
            while (!reader.atEnd()) {

                // 读取下一个元素
                QXmlStreamReader::TokenType nType = reader.readNext();

                switch (nType) {
//                case QXmlStreamReader::StartDocument: {  // 开始文档
//                 //   qDebug() << "********** 开始文档（XML 声明） ********** ";
//                    // XML 声明
//                    QString strVersion = reader.documentVersion().toString();
//                    QString strEncoding = reader.documentEncoding().toString();
//                    bool bAlone = reader.isStandaloneDocument();
//                 //   qDebug() << QString("版本：%1  编码：%2  Standalone：%3").arg(strVersion).arg(strEncoding).arg(bAlone) << "\r\n";
//                    break;
//                }

                case QXmlStreamReader::StartElement: {  // 开始元素
                    QString strElementName = reader.name().toString();
                    if (QString::compare(strElementName, "Item") == 0) {  // 根元素
                     //   qDebug() << QString("********** 开始元素<Item> ********** ");
                        QXmlStreamAttributes attributes = reader.attributes();
                        QString name,value;
                        if (attributes.hasAttribute("name")) {
                            name = attributes.value("name").toString();
                        }
                        if (attributes.hasAttribute("value")) {
                            value = attributes.value("value").toString();
                        }
                      //  qDebug() << name <<": "<<value;
                        XmlCfgItem item;
                        item.name = name.toStdString();
                        item.value = value.toStdString();
                        cfgItemVec.push_back(item);
                    }
                    break;
                }

                default:
                    break;
                }
            }

            if (reader.hasError()) {  // 解析出错
                qDebug() << QString("错误信息：%1  行号：%2  列号：%3  字符位移：%4").arg(reader.errorString()).arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.characterOffset());
            }

            file.close();  // 关闭文件
        }


        AttrCtrlMap::iterator it = m_attrMap.begin();
        for (; it != m_attrMap.end(); ++it)
        {
            if (it->second)
            {
                it->second->readCfg(m_cameraMgr->GetCurrentCamera(), cfgItemVec);
            }
        }
    });


	//connect(ui->btnSavePath, &QPushButton::clicked, [=] {
	//	QStringList list = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation);
	//	QString path = QFileDialog::getExistingDirectory(this, tr("Select save path..."), list.first());
	//
	//	if(!path.isEmpty())
	//	{
	//		m_savePath = path;
	//		QString appName = QCoreApplication::applicationName();
	//		QSettings app(appName, "Camera");
	//		app.setValue("SavePath", m_savePath);
	//		return;
	//	}
	//});

	connect(ui->btnIP, &QPushButton::clicked, [=] {
		IpDialog *dlg = new IpDialog(this);
		dlg->exec();
	});
}

void CameraDialog::InitListWidget()
{
    ui->listWidget->clear();
    CameraManager::InterfaceMap m = m_cameraMgr->GetAllCameraInterfaces();
	if (m.count() == 0)
	{
		ui->btnConnect->setEnabled(false);
		ui->btnIP->setEnabled(false);
	}
	else 
	{
		ui->btnConnect->setEnabled(true);
		ui->btnIP->setEnabled(true);
		QSettings app("Pin1Vision", "Camera");
		QString sn1 = app.value("camera1").toString();
		QString sn2 = app.value("camera2").toString();
		QString in1 = m_cameraMgr->GetInterfaceNameWithSerialNum(sn1);
		QString in2 = m_cameraMgr->GetInterfaceNameWithSerialNum(sn2);
		QSettings app3("TopVision", "Camera");
		QString sn3 = app.value("cameraTop").toString();
		QString in3 = m_cameraMgr->GetInterfaceNameWithSerialNum(sn3);
		for (CameraManager::InterfaceMap::Iterator it = m.begin(); it != m.end(); ++it)
		{
			std::string stdStr = it.key();
			QTextCodec* codec2 = QTextCodec::codecForName("GBK");
			QString s = codec2->toUnicode(stdStr.c_str(), stdStr.size());
			if (s.compare(in1, Qt::CaseInsensitive) && s.compare(in2, Qt::CaseInsensitive) && s.compare(in3, Qt::CaseInsensitive))
			{
				ui->listWidget->addItem(s);
			}
			m_cameraMgr->SelectCameraIndex(0);
			ui->listWidget->setCurrentRow(0);
		}
	} 
}

void CameraDialog::updateAttributeCtrl()
{
    qDebug()<<__func__;
    AttrCtrlMap::iterator it = m_attrMap.begin();
    for (; it != m_attrMap.end(); ++it)
    {
        if (it->second)
        {
            it->second->init(m_cameraMgr->GetCurrentCamera());
            it->second->updataStatus(m_cameraMgr->GetCurrentCamera());
        }
    }
}

void CameraDialog::SliderValueChanged()
{
    QSlider *slider = (QSlider *) sender();
    QVariant v = slider->property("id");
    int k = v.toInt();
    AttrCtrlBasePtr c = m_attrMap[k];
    c->updataValue(m_cameraMgr->GetCurrentCamera(), 1);
}

void CameraDialog::EditTextChanged()
{
    QLineEdit *edit = (QLineEdit *) sender();
    QVariant v = edit->property("id");
    int k = v.toInt();

    AttrCtrlBasePtr c = m_attrMap[k];
    c->updataValue(m_cameraMgr->GetCurrentCamera(), 0);
}

CameraDialog::~CameraDialog()
{
    delete ui;
}
//
//void CameraDialog::closeEvent(QCloseEvent *)
//{
//	if (m_serialLight->isOpen())
//	{
//		m_serialLight->close();
//	}
//	m_serialLight->deleteLater();
//}
